#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "MSTK.h"
#include <mpi.h>

int main(int argc, char *argv[]) {
  int i, ok;
  char mname[256],filename[256];
  char buf[256];
  char subfilename[256];
  Mesh_ptr mesh, recv_mesh, *submeshes;
  RepType rtype;
  /* default divide into two parts */
  int num = 2;
  int rank;

  /* command line parameter */
  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&num);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

  /* initialize MPI data type */
  MESH_InitializeMPI(num);

  /* Load the mesh */
  strcpy(mname,argv[1]);
  strcpy(filename,mname);
  strcat(filename,".mstk");
    
  /* master process read in and divide the mesh */
  if(rank == 0) { 
    /* Initialize MSTK - Always do this even if it does not seem to
    matter in this version of MSTK */
    MSTK_Init();  
    mesh = MESH_New(UNKNOWN_REP);
    ok = MESH_InitFromFile(mesh,filename);
    if (!ok) {
      fprintf(stderr,"Cannot open input file %s\n\n\n",filename);
      exit(-1);
    }
    fprintf(stdout,"mstk mesh %s read in successfully\n",filename);
    
    /* Partition the mesh*/
    rtype = MESH_RepType(mesh);
    submeshes = (Mesh_ptr *)MSTK_malloc((num)*sizeof(Mesh_ptr));
    ok = MESH_Partition(mesh,submeshes,num);
    fprintf(stdout,"%s has been partitioned into %d submeshes\n",filename,num);

    /* operation on submeshes */
    for(i = 0; i < num; i++) {  
      /* built ptype */
      MESH_BuildPType(mesh,submeshes[i]);
      /* add ghost */
      MESH_AddGhost(mesh,submeshes[i],1);
      if(i > 0) {
      /* send mesh */
	MESH_SendMesh(submeshes[i],i,MPI_COMM_WORLD);
      }
    }
  }

  /* receive mesh */
  if(rank == 0)
    /* submesh on the root */
    recv_mesh = submeshes[0];
  else {
    recv_mesh = MESH_New(R1);
    MESH_RecvMesh(recv_mesh,2,0,rank,MPI_COMM_WORLD);
    fprintf(stdout,"submesh %d received\n",rank);
  }

  /* build ghost list */
  MESH_BuildGhostList(recv_mesh,0);
  
  /* update ghost info */
  MESH_UpdateGhostInfo(recv_mesh, rank, num,  MPI_COMM_WORLD);
  extern int *global_ghost_info;

  printf("mesh %d number of gh vertex: %d ut vertex: %d\n",rank,global_ghost_info[rank*8],global_ghost_info[rank*8+1]);
  printf("mesh %d number of gh edge: %d ut edge: %d\n",rank,global_ghost_info[rank*8+2],global_ghost_info[rank*8+3]);
  printf("mesh %d number of gh face: %d ut face: %d\n",rank,global_ghost_info[rank*8+4],global_ghost_info[rank*8+5]);
  printf("mesh %d number of gh region: %d ut region: %d\n",rank,global_ghost_info[rank*8+6],global_ghost_info[rank*8+7]);
  
  MESH_FinalizeMPI();
  MPI_Finalize();
  return 1;
}

